namespace test10 {

    // 联合类型 |
    // 定义 ：联合类型使用竖线 | 分隔各个类型

    // 字符串字面量类型
    // 字符串字面量类型允许你指定字符串必须的固定值。

    type Easing = 'ease-in' | 'ease-out' | 'ease-in-out'
    class UIElement {
        animate(dx: number, dy: number, easing: Easing) {
            if (easing === 'ease-in') {

            } else if (easing === 'ease-out') {

            } else if (easing === 'ease-in-out') {

            } else {
                console.log('error!');

            }
        }
    }
    let button = new UIElement()
    button.animate(0, 0, 'ease-in')
    // 你只能从三种允许的字符中选择其一来做为参数传递, 传入其它值则会产生错误。


    // 数字字面量类型
    // TypeScript还具有数字字面量类型。
    function rollDile(): 1 | 2 | 3 | 4 | 5 | 6 {
        return 6
    }

    // 交叉类型 使用 & 符号来连接各个类型
    // 多种类型的集合，联合对象将具有所联合类型的所有成员
    interface People {
        age: number,
        height: number
    }
    interface Man {
        sex: string
    }

    const xiaoman = (man: People & Man) => {
        console.log(man.age)
        console.log(man.height)
        console.log(man.sex)
    }
    xiaoman({ age: 18, height: 180, sex: 'male' });

    // 类型断言
    // 用于手动指定一个值的类型，覆盖编译器的类型推断
    // 两种形式
    // 1、尖括号语法
    let someVlue1: any = 'this is a string'
    let stringth1: number = (<string>someVlue1).length
    // 2、as语法
    let someVlue2: any = 'this is a string'
    let stringth2: number = (someVlue2 as string).length


    // 联合类型和断言
    interface A {
        run: string
    }
    interface B {
        build: string
    }
    const fn = (type: A | B): string => {
        // return (type).run // 报错 类型“A | B”上不存在属性“run”。 类型“B”上不存在属性“run”。
        // 此时可以使用类型断言来推断它传入的是A接口的值
        return (type as A).run
    }

    // 使用any临时断言
    // window.abc = 123 // 报错，是因为window没有abc这个东西
    (window as any).abc = 123
    //可以使用any临时断言在 any 类型的变量上，访问任何属性都是允许的。


    // as const
    // 对于字面量的断言，与const直接定义常量是有区别的
    // 如果是普通类型跟直接const声明是一样的
    const names1 = '小曼'
    // names1 = 'aa' // 报错，const定义常量，无法修改

    let names2 = '小曼' as const
    // names2 = 'aa' // 报错 将names2断言成了字面量字符串，即它的值在初始化后不应该被修改

    let names3 = '小曼'
    names3 = 'aa'

    // 数组
    let a1 = [10, 20] as const
    const a2 = [10, 20];
    // a1.unshift(30) // 报错 ，因为 a1 被断言为一个常量数组，意味着它的内容不能被更改。
    a2.unshift(30)
    //a2 被声明为一个常量引用，但它本身并不是一个不可变的数组。
    // 这意味着你可以对 a2 进行读取，但不能重新赋值给 a2。
    // 然而，你可以修改 a2 的内容，比如使用 unshift 方法添加元素，这不会导致编译错误。

    // 总结：
    // 使用 as const 断言的数组是不可变的，不能对其内容进行任何修改。
    // 不使用 as const 断言的数组（即使使用 const 声明）可以修改其内容，但不能重新赋值给变量。





}